﻿using System;

namespace OperatorApplication
{
    /*
     运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C# 有丰富的内置运算符，分类如下：
        算术运算符
        关系运算符
        逻辑运算符
        位运算符
        赋值运算符
        其他运算符
     */
    class OperatorsApp1
    {
        /*
         所有算术运算符
            +   两个操作数相加
            -   第一个操作数减去第二个操作数
            *   两个操作数相乘
            /   分子除以分母
            %   取模运算符，整出后的余数
            ++  自增运算符，整数值增加 1
            --  自减运算符，整数值减少 1
         */
        /*
        static void Main(string[] args)
        {
            int a = 21;
            int b = 10;
            int c;

            c = a + b;
            Console.WriteLine("Line 1 - c 的值是{0}", c);
            c = a - b;
            Console.WriteLine("Line 2 - c 的值是{0}", c);
            c = a * b;
            Console.WriteLine("Line 3 - c 的值是{0}", c);
            c = a / b;
            Console.WriteLine("Line 4 - c 的值是{0}", c);
            c = a % b;
            Console.WriteLine("Line 5 - c 的值是{0}", c);

            c = ++a;
            Console.WriteLine("Line 6 - c 的值是{0}", c);
            c = --a;
            Console.WriteLine("Line 7 - c 的值是{0}", c);
            Console.ReadLine();
            // ++a先++后赋值 a++先赋值后++
        }
        */
    }

    class OperatorsApp2
    {
        /*
         所有逻辑运算符
         &&     逻辑与运算符 两个操作数都非零，则条件为0
         ||     逻辑或运算符，两个操作数中任意一个非零，则条件为真
         ！     逻辑非运算符，逆转操作数的逻辑状态。如果条件为真则逻辑非运算符则将其为假
         */
        static void Op2()
        {
            bool a = true;
            bool b = true;

            if (a && b)
            {
                Console.WriteLine("Line 1 - 条件为真");
            }
            if (a || b)
            {
                Console.WriteLine("Line 2 - 条件为真");
            }
            /* 改变 a 和 b 的值 */
            a = false;
            b = true;
            if (a && b)
            {
                Console.WriteLine("Line 3 - 条件为真");
            }
            else 
            {
                Console.WriteLine("Line 3 - 条件不为真");
            }
            if (!(a && b))
            {
                Console.WriteLine("Line 4 - 条件为真");
            }
            Console.ReadLine();
        }
    }

    class OperatorApp3
    {
        /*
            所有位运算符
            &   同时存在两个操作数中，二进制 AND 运算符赋值一位到结果中
            |   存在于任意操作数中， 二进制 OR 运算符赋值一位到结果中
            ^   存在于其中一个操作数中但不同时存在于两个操作数中，二进制异或运算符一位到结果中
            ~   按为取反符是一元运算符，具有"翻转"位效果，即0变成1，1变成0，包括符号位
            <<  二进制左移运算符。左操作数的值向左移动右操作数指定的位数
            >>  二进制右移运算符。左操作数的值向右移动右操作数指定的位数
         */
        static void Op3()
        {
            int a = 60;
            int b = 13;
            int c = 0;

            c = a & b;
            Console.WriteLine("Line 1 - c 的值是{0}", c);

            c = a | b;
            Console.WriteLine("Line 2 - c 的值是{0}", c);

            c = a ^ b;
            Console.WriteLine("Line 3 - c 的值是{0}", c);

            c = ~a;
            Console.WriteLine("Line 4 - c 的值是{0}", c);

            c = a << 2;
            Console.WriteLine("Line 5 - c 的值是{0}", c);

            c = a >> 2;
            Console.WriteLine("Line 6 - c 的值是{0}", c);
            Console.ReadLine();
        }
    }

    class OperatorApp4
    { 
        /*
         所有赋值运算符
            =       简单赋值运算符 把右边的操作数的值赋给左边操作数
            +=      加且赋值运算符 把右边操作数加上左边操作数的结果赋值给左边操作数
            -=      减且赋值运算符 把左边操作数减去右边操作数的结果赋值给左边操作数
            *=      乘且赋值运算符 把右边操作数乘以左边操作数的结果赋值给左边操作数
            /=      除且赋值运算符 把左边操作数除以右边操作数的结果赋值给左边操作数
            %=      求模且赋值运算符 求两个操作数的模赋值给左边操作数
            <<=     左移且赋值运算符
            >>=     右移且赋值运算符
            &=      按位与且赋值运算符
            ^=      按位异或且赋值运算符
            |=      按位或且赋值运算符
         */
        static void Op4()
        {
            int a = 21;
            int c;

            c = a;
            Console.WriteLine("Line 1 - = c 的值 = {0}", c);

            c += a;
            Console.WriteLine("Line 2 - += c 的值 = {0}", c);

            c -= a;
            Console.WriteLine("Line 3 - -= c 的值 = {0}", c);

            c *= a;
            Console.WriteLine("Line 4 - *= c 的值 = {0}", c);

            c /= a;
            Console.WriteLine("Line 5 - /= c 的值 = {0}", c);

            c = 200;
            c %= a;
            Console.WriteLine("Line 6 - %= c 的值 = {0}", c);

            c <<= 2;
            Console.WriteLine("Line 7 - <<= c 的值 = {0}", c);

            c >>= 2;
            Console.WriteLine("Line 8 - >>= c 的值 = {0}", c);

            c &= 2;
            Console.WriteLine("Line 9 - &= c 的值 = {0}", c);

            c ^= 2;
            Console.WriteLine("Line 10 - ^= c 的值 = {0}", c);

            c |= 2;
            Console.WriteLine("Line 11 - |= c 的值 = {0}", c);
            Console.ReadLine();
        }
    }

    class OperatorApp5
    { 
        /*
         其他运算符
            C#支持的其他一些重要的运算符，包括 sizeof、typeof 和 ?:
            sizeof      返回数据类型的大小
            typeof      返回class的类型
            &           返回变量的地址
            *           变量的指针
            ?:          条件表达式
            is          判断对象是否位某一类型
            as          强制转换，即使转换失败也不会抛出异常
         */
        void Op5()
        {
            // sizeof 运算符的实例
            Console.WriteLine("int 的大小是 {0}", sizeof(int));
            Console.WriteLine("short 的大小是 {0}", sizeof(short));
            Console.WriteLine("double 的大小是 {0}", sizeof(int));

            // 三元运算符的实例
            int a, b;
            a = 10;
            b = (a == 1) ? 20 : 30;
            Console.WriteLine("b 的值是 {0}", b);

            b = (a == 10) ? 20 : 30;
            Console.WriteLine("b 的值是 {0}", b);
            Console.ReadLine();

            // typeof 关键字用于获取一个类型的类型对象，通常用于反射和动态创建类型的实例
            Type type = typeof(OperatorApp3);
            Console.WriteLine(type.FullName);
            Console.ReadKey();
        }
    }
}